package me.szlx.region;

import me.szlx.thing.*;

import java.util.Objects;

/**
 * Created by shenzhilin on 2017-4-19.
 */
public interface Region extends Thing {
    default boolean isProvince() {
        return match(Regions.Type.PROVINCE.getTrait());
    }

    default boolean isCity() {
        return match(Regions.Type.CITY.getTrait());
    }

    default boolean isDistrict() {
        return match(Regions.Type.DISTRICT.getTrait());
    }

    default String getFullName() {
        return isProvince() ? getName() : expanding().getFullName() + getName();
    }

    /**
     * 获取更大一级区域。区县更大一级是市，市更大一个是省，省更大一级是自身。
     *
     * @return 更大一级的区域。
     */
    default Region expanding() {
        if (isProvince()) {
            return this;
        }
        Integer thisId = (Integer) getId();
        return isCity() ? Regions.get(thisId - thisId % 10000) : Regions.get(thisId - thisId % 100);
    }

    default boolean like(Thing thing, TraitLet... traits) {
        if (thing == null || !(thing instanceof Region)) {
            return false;
        }
        Integer thisId = (Integer) getId();
        Integer thatId = (Integer) thing.getId();
        for (Trait trait : Trait.marshal(traits)) {
            if (Regions.Type.PROVINCE.getTrait().match(trait, Trait.MatchAction.NAME_AND_VALUE)) {
                if (thisId / 10000 != thatId / 10000) {
                    return false;
                }
            } else if (Regions.Type.CITY.getTrait().match(trait, Trait.MatchAction.NAME_AND_VALUE)) {
                if (thisId / 100 != thatId / 100) {
                    return false;
                }
            } else if (Regions.Type.DISTRICT.getTrait().match(trait, Trait.MatchAction.NAME_AND_VALUE)) {
                if (thisId != thing.getId()) {
                    return false;
                }
            } else {
                if (match(trait) != thing.match(trait)) {
                    return false;
                }
            }
        }
        return true;
    }

    class Creator implements ThingCreator<Region> {
        static Creator newInstance() {
            return new Creator();
        }

        @Override
        public Region create(Object code, String name, String description, Traits traits) {
            Objects.requireNonNull(code, "区域代码不能null");
            Objects.requireNonNull(name, "区域名称不能为null");
            Integer theCode = code instanceof Integer ? (Integer) code : (Integer.valueOf(code.toString()));

            Trait regionTrait = traits != null ? traits.ofName(Regions.TRAIT_NAME) : null;
            if (regionTrait == null) {
                if (theCode % 10000 == 0) {
                    regionTrait = Regions.Type.PROVINCE.getTrait();
                } else if (theCode % 100 == 0) {
                    regionTrait = Regions.Type.CITY.getTrait();
                } else {
                    regionTrait = Regions.Type.DISTRICT.getTrait();
                }
                traits = Traits.of(traits, regionTrait);
            }
            RegionVO vo = new RegionVO();
            vo.setId(code);
            vo.setName(name);
            vo.setDescription(description);
            vo.setTraits(traits);
            return vo;
        }
    }
}

class RegionVO extends ThingVO implements Region {
}
